/**************************************************************************//**
 * @file           main.c
 * @version        V1.0
 * $Revision:      1 $
 * $Date:          2017/01/04 $
 * @brief          Main function
 * @Author         Jeffrey Kang
 * @ContactInfo    chkang@esmt.com.tw
 *
 * @note
 *
 * Copyright (C) 1998 Elite Semiconductor Memory Technology Corp.
 * All rights reserved.
 *
 ******************************************************************************/


#include <REG52.h>
#include "system_FE81001.h"

#define FRAME_SEG_SIZE 14

void RTD_measure_show(void);
void RTD_show();
void TMR0Init(void);
void TMR1Init(void);

static volatile unsigned char raw_data[3] = {0};

xdata long unsigned int R0_ADC = 4585196;

long unsigned int R_ADC = 0 ; 

float alpha = 0.003258517;

unsigned char flag_RTD = 1 ;
unsigned char flag_ADC = 0 ;
unsigned char flag_light = 0 ;

 int  Temp =0 ;

unsigned count =0 ;
int Temp_0  = 0; 
int Temp_1  = 0; 
int Temp_avg  = 0; 

float b = 0;

unsigned int bb = 0 ;

unsigned char PWM_UP[34]={0,0,0,0,1,1,2,3,4,	6,10	,12,15,16,18,	20,	22,30,32,34,38,40,	42,	56,65,	72,85,	90,	110,120,	132,	156,240,255};

/**
 * @brief       delay function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */

void delay (int cnt )
{
	unsigned int i , j ;
	
	for(j=0 ; j<cnt ; j++)
	for( i = 0 ; i < 200 ; i++ ); 
	
}


/**
 * @brief       SDMISR function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
const void SDMISR (void) interrupt ISR_SDM
{
	unsigned char int_stat = SDM->intstat;                // clear interrupt flag
	
	SDM->intstat = 0x81;
	
	/* fetch calibration data */
	raw_data[0] = SDM->rawdata[0];	// L_byte
	raw_data[1] = SDM->rawdata[1];	// M_byte
	raw_data[2] = SDM->rawdata[2];  // H_byte

	R_ADC =  raw_data[2]*65536 + raw_data[1]*256 +raw_data[0];
	
	flag_ADC =1 ;
	
	/* enable global interrupt */
	//INTC->int_gmask = 0x01;
}


void LCMInit()
{
  	unsigned char i;
  	
  	/* LCD clock enable */
  	En_LCM_clk();
  	
  	/* LCD control register setting */
  	LCM->control0 = 0x41;				// 0, ENLCDBUF = 1, freq = 0 (60Hz) 1(120Hz), LEVEL = 1(1/3 bias) 1(1/2 bias), VCTR = 0001
  	
  	/* Reset Frame Buffer */
  	for( i = 6 ; i < FRAME_SEG_SIZE ; i++ ){
  		LCM->frambuf[i] = 0x00;
		}
	
		LCM_on();
	
}

/**
 * @brief       SDMConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void SDMConfig ()
{
		// RTD
	
		//Set OSR
		OSR_32768();
	
		//Set INMUX
		Set_input_channel_Ch6();
	
		//Set Rmux
		Set_Vref_1p2V();
		
		//Set INBUF
		Enable_Input_buffer();
		
		//Set VRBUF
		Enable_Vref_buffer();
	
		//Set Vref Gain
		Set_Vref_Gain_x1_div4(); // 1/4Vref  -> 1.2/4 = 0.3V
	
		//Set ADCGN
		Set_ADC_Gain_x1();
		
		//Enable TMPSNS
		Enable_TMPSNS();
		
		//	Enable Interrupt
		Enable_SDM_inerrupt();

}

void SDM_light_config()
{
			Set_input_channel_Ch5();
	
			Set_Vref_Gain_x1();
}

void light_show()
{
		flag_ADC = 0 ;
	
		if(	R_ADC > 2000000)
		{
				PB3 = 0;
		}
		
		else
		{
				PB3 = 1;
		}
	
}



/**
 * @brief       ANACConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void ANACConfig ()
{
	//	RTD
	Enable_BIAS();
	Enable_LDOA();
	Enable_VCM();
	
	//	Enable DAC1P
	Enable_DAC1P();
	
	//	Enable PSW
	Enable_PSW();
	
	//	Enable DAC1
	Enable_IDAC1();
	
	//	Set DAC1 Current 
	Set_IDAC1_Current(Current_1200uA);
	
}

/**
 * @brief       IOConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void IOConfig()
{
	/* Set PC7 input as button */
	PORT_SetPCInput(BIT7);

	/* Set PD1. ,PD2.,PD3 output */
	PORT_SetPDPushPull(BIT1 | BIT2 | BIT3 );

	//	LCM
	
	/* enable PD input mode */
	PORT_SetPDInput( BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7 );
	
	/* enable PC input mode */
	PORT_SetPCInput(BIT0 | BIT1);
	
	/* enable PB input mode */
	PORT_SetPBInput(BIT6 | BIT7);
	
	/* Set PD4 as COM3 */
	Set_PD4_COM3();
	
	/* Set PD5 as COM2 */
	Set_PD5_COM2();
	
	/* Set PD6 as COM1 */
	Set_PD6_COM1();
	
	/* Set PD7 as COM0 */
	Set_PD7_COM0();

	/* Set PD0 as SEG03 */
	Set_PD0_SEG03();
	
	/* Set PD1 as SEG02 */
	Set_PD1_SEG02();
	
	/* Set PD2 as SEG01 */
	Set_PD2_SEG01();
	
	/* Set PD3 as SEG00 */
	Set_PD3_SEG00();
	
	/* Set PC0 as SEG11 */
	Set_PC0_SEG11();
	
	/* Set PC1 as SEG10 */
	Set_PC1_SEG10();
	
	/* Set PB6 as SEG13 */
	Set_PB6_SEG13();
	
	/* Set PB7 as SEG12 */
	Set_PB7_SEG12();
	
		/* enable PB.4 PB.5 PB.6 output */
	PORT_SetPBPushPull(BIT4 | BIT5);
	
		/* enable PB.4 PB.5 PB.6 PWM */
	Set_PB4_PWM0();
	Set_PB5_PWM1();
	
	PORT_SetPBPushPull(BIT3);
	
	
}


/**
 * @brief       CLKConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void CLKConfig()
{
	/* enable GPIO clock */
	PORT_PAPBPCPD_Clock_Enable();
	
	/* enable SDM & ANA clock */
	En_SDM_clk();
	En_ANA_clk();
	
	/* sdm clock divider */
	Set_SDM_clk_250K();   
	
	/* TMR0, TMR1, TMR2, clock selection : 0 -> PCLK, 1 -> LSRC */
	Timer0_clock_PCLK();
	
	/* enable TMR0, TMR1, TMR2 clock divider */
	Timer0_clock_Div_4();
	Timer1_clock_Div_4();
	
	/* enable TMR0, TMR1 clock */
	En_Timer0_clk();
	En_Timer1_clk();
	
}

void Dig1( unsigned int num)
{
	switch(num)
	{
		
	    	case 0:
	    			LCM->frambuf[0]  = 0x0B;
	    			LCM->frambuf[1]  = 0x0E;
	    			break ;
	    	
	    	case 1:
	    			LCM->frambuf[0]  = 0x00;
	    			LCM->frambuf[1]  = 0x06;
	    		break ;
	    	
	    	case 2:
	    			LCM->frambuf[0]  = 0x07;
	    			LCM->frambuf[1]  = 0x0C;
	    		break ;
	    	
	    	case 3:
	    			LCM->frambuf[0]  = 0x05;
	    			LCM->frambuf[1]  = 0x0E;
	    		break ;
	    	
	    	case 4:
	    			LCM->frambuf[0]  = 0x0C;
	    			LCM->frambuf[1]  = 0x06;
	    		break ;
	    	
	    	case 5:
	    			LCM->frambuf[0]  = 0x0D;
	    			LCM->frambuf[1]  = 0x0A;
	    		break ;
	    	
	    	case 6:
	    			LCM->frambuf[0]  = 0x0F;
	    			LCM->frambuf[1]  = 0x02;
	    		break ;
	    	
	    	case 7:
	    			LCM->frambuf[0]  = 0x00;
	    			LCM->frambuf[1]  = 0x0E;
	    		break ;
	    	
	    	case 8:
	    			LCM->frambuf[0]  = 0x0F;
	    			LCM->frambuf[1]  = 0x0E;
	    		break ;
	    	
	    	case 9:
	    			LCM->frambuf[0]  = 0x0C;
	    			LCM->frambuf[1]  = 0x0E;
	    		break ;
		
	}
	
}
void Dig2( unsigned int num)
{
	switch(num)
	{
		
	    	case 0:
	    			LCM->frambuf[2]  = 0x0B;
	    			LCM->frambuf[3]  = 0x0E;
	    			break ;
	    	
	    	case 1:
	    			LCM->frambuf[2]  = 0x00;
	    			LCM->frambuf[3]  = 0x06;
	    		break ;
	    	
	    	case 2:
	    			LCM->frambuf[2]  = 0x07;
	    			LCM->frambuf[3]  = 0x0C;
	    		break ;
	    	
	    	case 3:
	    			LCM->frambuf[2]  = 0x05;
	    			LCM->frambuf[3]  = 0x0E;
	    		break ;
	    	
	    	case 4:
	    			LCM->frambuf[2]  = 0x0C;
	    			LCM->frambuf[3]  = 0x06;
	    		break ;
	    	
	    	case 5:
	    			LCM->frambuf[2]  = 0x0D;
	    			LCM->frambuf[3]  = 0x0A;
	    		break ;
	    	
	    	case 6:
	    			LCM->frambuf[2]  = 0x0F;
	    			LCM->frambuf[3]  = 0x02;
	    		break ;
	    	
	    	case 7:
	    			LCM->frambuf[2]  = 0x00;
	    			LCM->frambuf[3]  = 0x0E;
	    		break ;
	    	
	    	case 8:
	    			LCM->frambuf[2]  = 0x0F;
	    			LCM->frambuf[3]  = 0x0E;
	    		break ;
	    	
	    	case 9:
	    			LCM->frambuf[2]  = 0x0C;
	    			LCM->frambuf[3]  = 0x0E;
	    		break ;
		
	}
	
}
void Dig3( unsigned int num)
{
	switch(num)
	{
		
	    	case 0:
	    			LCM->frambuf[10]  = 0x0B;
	    			LCM->frambuf[11]  = 0x0E;
	    			break ;
	    	
	    	case 1:
	    			LCM->frambuf[10]  = 0x00;
	    			LCM->frambuf[11]  = 0x06;
	    		break ;
	    	
	    	case 2:
	    			LCM->frambuf[10]  = 0x07;
	    			LCM->frambuf[11]  = 0x0C;
	    		break ;
	    	
	    	case 3:
	    			LCM->frambuf[10]  = 0x05;
	    			LCM->frambuf[11]  = 0x0E;
	    		break ;
	    	
	    	case 4:
	    			LCM->frambuf[10]  = 0x0C;
	    			LCM->frambuf[11]  = 0x06;
	    		break ;
	    	
	    	case 5:
	    			LCM->frambuf[10]  = 0x0D;
	    			LCM->frambuf[11]  = 0x0A;
	    		break ;
	    	
	    	case 6:
	    			LCM->frambuf[10]  = 0x0F;
	    			LCM->frambuf[11]  = 0x02;
	    		break ;
	    	
	    	case 7:
	    			LCM->frambuf[10]  = 0x00;
	    			LCM->frambuf[11]  = 0x0E;
	    		break ;
	    	
	    	case 8:
	    			LCM->frambuf[10]  = 0x0F;
	    			LCM->frambuf[11]  = 0x0E;
	    		break ;
	    	
	    	case 9:
	    			LCM->frambuf[10]  = 0x0C;
	    			LCM->frambuf[11]  = 0x0E;
	    		break ;
		
	}
}
void Dig4( unsigned int num)
{
	switch(num)
	{
		
	    	case 0:
	    			LCM->frambuf[12]  = 0x0B;
	    			LCM->frambuf[13]  = 0x0E;
	    			break ;
	    	
	    	case 1:
	    			LCM->frambuf[12]  = 0x00;
	    			LCM->frambuf[13]  = 0x06;
	    		break ;
	    	
	    	case 2:
	    			LCM->frambuf[12]  = 0x07;
	    			LCM->frambuf[13]  = 0x0C;
	    		break ;
	    	
	    	case 3:
	    			LCM->frambuf[12]  = 0x05;
	    			LCM->frambuf[13]  = 0x0E;
	    		break ;
	    	
	    	case 4:
	    			LCM->frambuf[12]  = 0x0C;
	    			LCM->frambuf[13]  = 0x06;
	    		break ;
	    	
	    	case 5:
	    			LCM->frambuf[12]  = 0x0D;
	    			LCM->frambuf[13]  = 0x0A;
	    		break ;
	    	
	    	case 6:
	    			LCM->frambuf[12]  = 0x0F;
	    			LCM->frambuf[13]  = 0x02;
	    		break ;
	    	
	    	case 7:
	    			LCM->frambuf[12]  = 0x00;
	    			LCM->frambuf[13]  = 0x0E;
	    		break ;
	    	
	    	case 8:
	    			LCM->frambuf[12]  = 0x0F;
	    			LCM->frambuf[13]  = 0x0E;
	    		break ;
	    	
	    	case 9:
	    			LCM->frambuf[12]  = 0x0C;
	    			LCM->frambuf[13]  = 0x0E;
	    		break ;
		
	}
	
}
	
void point()
{
		LCM->frambuf[3]  |= 0x01;
}

void TimerInit()
{
		TMR0Init();
	//	TMR1Init();
}
/**
 * @brief       main function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
int main (void)
{
	int  i  = 0; 
	CLKConfig();
	IOConfig();
	
	LCMInit();
	ANACConfig();
	SDMConfig();
	TimerInit();
	
	/* enable global interrupt */
	INTC->int_gmask = 0x01;
	
	delay(1);
	
  while(1)
   {

				for(i = 0 ; i<34; i++)
				{
						TMR0->reload0[0] = 0x00;			
						TMR0->reload0[1] = 255-PWM_UP[i];			
						TMR0->reload0[2] = 0x00;			
						TMR0->reload0[3] = PWM_UP[i];		
					
						TMR0->reload1[0] = 0x00;		
						TMR0->reload1[1] = 255-PWM_UP[i];			
						TMR0->reload1[2] = 0x00;			
						TMR0->reload1[3] = PWM_UP[i];		
						
						delay(60);	
					
	        	if(flag_ADC == 1 && flag_RTD ==1 )
	     			{

								flag_RTD = 0;
	     					flag_light = 1;
	     					RTD_measure_show();
								RTD_show();
	     					
	     					SDM_light_config();
	     					INTC->int_gmask = 0x01;
	     			}
	     			
	     			if(flag_ADC == 1 && flag_light ==1 )
	     			{
	     					flag_light = 0;
	     					flag_RTD =1;
	     					light_show();
	     				
	     					SDMConfig();
	     					INTC->int_gmask = 0x01;
	        	}
				}
	
					for(i = 32; i>0 ; i--)
     		{
     				
           	TMR0->reload0[0] = 0x00;		
           	TMR0->reload0[1] = 255-PWM_UP[i];			
           	TMR0->reload0[2] = 0x00;			
           	TMR0->reload0[3] = PWM_UP[i];		
					
					  TMR0->reload1[0] = 0x00;			
           	TMR0->reload1[1] = 255-PWM_UP[i];			
           	TMR0->reload1[2] = 0x00;		
           	TMR0->reload1[3] = PWM_UP[i];		
					
						delay(60);	
					
						if(flag_ADC == 1 && flag_RTD ==1 )
						{
								flag_RTD = 0;
								flag_light = 1;
								RTD_measure_show();
							RTD_show();
								
								SDM_light_config();
								INTC->int_gmask = 0x01;
						}
						
						if(flag_ADC == 1 && flag_light ==1 )
						{
								flag_light = 0;
								flag_RTD =1;
								light_show();
							
								SDMConfig();
								INTC->int_gmask = 0x01;
						}
						
     	}
	
   }
	 
}

void RTD_measure_show()
{
		count ++;
	
	   flag_ADC =  0; 
     
     Temp = ( ( (float)R_ADC /(float) R0_ADC - 1.0) / alpha)*100 ; 
	
		if(count ==1 )
		{
				Temp_0 = Temp;
				Temp_avg = Temp_0;
		}
		
		if(count ==2 )
		{
				Temp_1 = Temp;
				Temp_avg = Temp_1*0.8+Temp_0*0.2;
		}
		
		if(count >=2 )
		{
				Temp_avg = Temp*0.8+Temp_avg*0.2;
				count = 3;
		}
		
}

void RTD_show()
{
			b =  ((float)Temp_avg /10.0) - (int)((float)Temp_avg /10.0);					
		bb = (b*10);
	
		// LCM
		
		 Dig1((unsigned int)((float)Temp_avg/1000.0));
		 Dig2(((unsigned int)((float)Temp_avg/100.0) % 10) );
	    point();
	    Dig3(((unsigned int)((float)Temp_avg/10.0) % 10) );
	    Dig4( bb);
	
}

void TMR0Init(void)
{
	/* TMR0 control setting */
	Timer0_CH0_Mode(Mode_PWM);
	Timer0_CH1_Mode(Mode_PWM);
	
	/* TMR0 Ch0 reload setting */
	TMR0->reload0[0] = 0x00;			//  PWM High Level Width - H_byte =  0x00(99)
	TMR0->reload0[1] = 0x63;			//	PWM High Level Width - L_byte  =  0x63(99)
	TMR0->reload0[2] = 0x00;			// 	PWM Low Level Width - H_byte  =  0x00(99)
	TMR0->reload0[3] = 0x63;			//  PWM Low Level Width - L_byte   =  0x63(99)

	/* TMR0 Ch1 reload setting */
	TMR0->reload1[0] = 0x03;			// 	PWM High Level Width - H_byte =  0x03(999)
	TMR0->reload1[1] = 0xE7;			//  PWM High Level Width - L_byte  =  0xE7(999)
	TMR0->reload1[2] = 0x03;			//  PWM Low Level Width - H_byte  =  0x03(999)
	TMR0->reload1[3] = 0xE7;			//  PWM Low Level Width - L_byte   =  0xE7(999)
	
	/* interrupt enable setting */
	
	/* timer start */
	Timer0_Start_Enable(Ch0_Timer3 | Ch1_Timer3);
	
}

void TMR1Init(void)
{
		/* TMR1 control setting */
	Timer1_CH0_Mode(Mode_PWM);
	Timer1_CH1_Mode(Mode_PWM);
	
	/* TMR1 Ch0 reload setting */
	TMR1->reload0[0] = 0x00;			//  PWM High Level Width - H_byte =  0x00(99)
	TMR1->reload0[1] = 0x63;			//	PWM High Level Width - L_byte  =  0x63(99)
	TMR1->reload0[2] = 0x00;			// 	PWM Low Level Width - H_byte  =  0x00(99)
	TMR1->reload0[3] = 0x63;			//  PWM Low Level Width - L_byte   =  0x63(99)

	/* TMR1 Ch1 reload setting */
	TMR1->reload1[0] = 0x03;			// 	PWM High Level Width - H_byte =  0x03(999)
	TMR1->reload1[1] = 0xE7;			//  PWM High Level Width - L_byte  =  0xE7(999)
	TMR1->reload1[2] = 0x03;			//  PWM Low Level Width - H_byte  =  0x03(999)
	TMR1->reload1[3] = 0xE7;			//  PWM Low Level Width - L_byte   =  0xE7(999)
	
	/* interrupt enable setting */
	
	/* timer start */
	Timer1_Start_Enable(Ch0_Timer3 | Ch1_Timer3);
}
